﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using UnityScriptEngine;

namespace EnrollmentSystem
{
    public partial class frmCourseEnlistment : Form
    {
        UnityProcessor proc = new UnityProcessor();
        Threader t = new Threader();
        UnityScript[] dat = new UnityScript[0];

        //Operation Attributes
        bool AddNew = false;
        int curEdit = -1;
        UnityElement curData;
        string prevSrc = "";

        public frmCourseEnlistment()
        {
            InitializeComponent();
            InitializeFrameSliderForm();
        }
        private void InitializeForm()
        {
            DoEvents();

            DetailControl(true);
            grpDetails.Visible = false;
            LoadSchoolYear();
        }

        void DoEvents()
        {
            //GUI Events
            btnAdd.Click += new EventHandler(delegate
            {
                //Proper Add New GUI
                AddNew = true;
                btnDelete.Enabled = false;
                //Format Time
                txtStartTime.Value = RoundOffTime(txtStartTime.Value.TimeOfDay);
                txtEndTime.Value = txtStartTime.Value.AddHours(1d);
                
                //DetailControl(true);
                UnityScript u = new UnityScript("LOADSUBJECTS", 5);
                u.Script_Add(Script.DBPUX_BEGIN);
                //u.Script_Add(Script.DBPUX_QUERY, string.Format("SELECT fID, fData ,fStamp FROM tbllookup WHERE fKey='SUBJECTS_OFFERED' AND "+
                //    "fData NOT IN(SELECT fCode FROM tblsubjectplanner WHERE fSchoolYear='{0}')",
                //    txtSchoolYear.Text
                //    ));
                u.Script_Add(Script.DBPUX_QUERY, string.Format("SELECT fID, fData ,fStamp FROM tbllookup WHERE fKey='SUBJECTS_OFFERED'",
                    txtSchoolYear.Text
                    ));
                u.Script_Add(Script.DBPUX_QUERY, "SELECT fID, fData, fStamp FROM tbllookup WHERE fKey='ROOM_LIST'");
                u.Script_Add(Script.DBPUX_COMMIT);
                proc.Run(u);
            });
            btnCancel.Click += new EventHandler(delegate
            {

                AddNew = false;
                DetailControl(false);
                foreach (Control ctl in grpDetails.Controls)
                {
                    if (ctl is TextBox) ((TextBox)ctl).Text = "";
                    if (ctl is ComboBox) ((ComboBox)ctl).SelectedIndex = -1;
                    if (ctl is DateTimePicker) ((DateTimePicker)ctl).Value = DateTime.Now;
                    if (ctl is CheckBox) ((CheckBox)ctl).Checked = false;
                    if (ctl is NumericUpDown) ((NumericUpDown)ctl).Value = 0;
                }
            });
            btnSave.Click += new EventHandler(delegate
            {
                SaveSubjectPlanner();
                grpDetails.Enabled = false;
            });
            btnDelete.Click += new EventHandler(delegate
            {
                if (MessageBox.Show("Do you wish to continue?",
                    "Delete Schedule",
                    MessageBoxButtons.YesNo,
                    MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.No) return;
                DeleteStudentProfile();
                grpDetails.Enabled = false;
            });
            grdItems.DoubleClick += new EventHandler(delegate
            {
                curEdit = grdItems.SelectedRows[0].Index;
                AddNew = false;
                dat[0].Data_Get(curEdit, out curData);

                UnityScript u = new UnityScript("LOADSUBJECTS", 5);
                u.Script_Add(Script.DBPUX_BEGIN);
                //u.Script_Add(Script.DBPUX_QUERY, string.Format("SELECT fID, fData ,fStamp FROM tbllookup WHERE fKey='SUBJECTS_OFFERED' AND " +
                //    "fData NOT IN(SELECT fCode FROM tblsubjectplanner WHERE fSchoolYear='{0}' AND NOT fCode='{1}')",
                //    txtSchoolYear.Text,
                //    curData.Data_GetField(0).ToString()
                //    ));
                u.Script_Add(Script.DBPUX_QUERY, string.Format("SELECT fID, fData ,fStamp FROM tbllookup WHERE fKey='SUBJECTS_OFFERED'",
                    txtSchoolYear.Text
                    ));
                u.Script_Add(Script.DBPUX_QUERY, "SELECT fID, fData, fStamp FROM tbllookup WHERE fKey='ROOM_LIST'");
                u.Script_Add(Script.DBPUX_COMMIT);
                proc.Run(u);

                btnDelete.Enabled = true;
                //DetailControl(true);
                
            });
            txtSearch.KeyPress += new KeyPressEventHandler(delegate(object sender, KeyPressEventArgs e)
            {
                if (e.KeyChar == (char)13)
                {
                    txtPage.Value = 1m;
                    prevSrc = txtSearch.Text;
                    LoadSchoolYear();
                }
            });
            txtPage.ValueChanged += new EventHandler(delegate
            {
                LoadSchoolYear();
            });
            txtSchoolYear.SelectedIndexChanged += new EventHandler(delegate
            {
                txtSchoolYear.Enabled = false;
                LoadSubjectPlanner();
            });
            //UnityScriptEngine Events
            proc.ProcessCompleted += new ProcessHandler(proc_ProcessCompleted);
            proc.ProcessError += new ProcessHandler(proc_ProcessError);
        }
        //UnityScriptEngine
        void proc_ProcessError(string id, string desc)
        {
            t.SafeCall(this, delegate
            {
                MessageBox.Show(desc);
                switch (id)
                {
                    case "LOADUSERS":
                        DetailControl(true);
                        grpDetails.Enabled = false;
                        break;
                    case "DELETEUSER":
                    case "SAVEUSER":
                        DetailControl(true);
                        break;
                }
            });
        }
        void proc_ProcessCompleted(string id, string desc)
        {
            t.SafeCall(this, delegate
            {
                switch (id)
                {
                    case "LOADSCHOOLYEAR":
                        UnityScript[] usy;
                        proc.DBPUX_Data_Fetch(out usy);
                        //grdItems.usyaSource = usy[0].TousyaTable();
                        if (usy[0].Data_Count == 50)
                            txtPage.Maximum = txtPage.Value + 1;
                        else
                            txtPage.Maximum = txtPage.Value;

                        txtSchoolYear.Items.Clear();
                        txtSchoolYear.Items.AddRange(usy[0].ToList(0));

                        txtSubject.Items.Clear();
                        txtSubject.Items.AddRange(usy[1].ToList(0));

                        txtVenue.Items.Clear();
                        txtVenue.Items.AddRange(usy[2].ToList(0));

                        txtPrice.Value = int.Parse(usy[3].ToList(0)[0].ToString());
                        DetailControl(false);
                        break;
                    case "DELETEUSER":
                    case "SAVEPLANNER":
                    case "LOADPLANNER":
                        proc.DBPUX_Data_Fetch(out dat);
                        grdItems.DataSource = dat[0].ToDataTable();
                        txtSchoolYear.Enabled = true;

                        AddNew = false;
                        DetailControl(false);
                        foreach (Control ctl in grpDetails.Controls)
                        {
                            if (ctl is TextBox) ((TextBox)ctl).Text = "";
                            if (ctl is ComboBox) ((ComboBox)ctl).SelectedIndex = -1;
                            if (ctl is DateTimePicker) ((DateTimePicker)ctl).Value = DateTime.Now;
                            if (ctl is CheckBox) ((CheckBox)ctl).Checked = false;
                        }
                        FormatGrid();
                        break;
                    case "LOADSUBJECTS":
                        
                        UnityScript[] usub;
                        proc.DBPUX_Data_Fetch(out usub);
                        
                        txtSubject.Items.Clear();
                        txtSubject.Items.AddRange(usub[0].ToList(0));
                        txtVenue.Items.Clear();
                        txtVenue.Items.AddRange(usub[1].ToList(0));
                        if (!AddNew)
                        {
                            txtSubject.Text = curData.Data_GetField(0).ToString();
                            txtStartTime.Value = DateTime.Parse(curData.Data_GetField(2).ToString());
                            txtEndTime.Value = DateTime.Parse(curData.Data_GetField(3).ToString());
                            txtVenue.Text = curData.Data_GetField(4).ToString();
                            txtPrice.Value = int.Parse(curData.Data_GetField(5).ToString());
                            txtUnits.Value = int.Parse(curData.Data_GetField(6).ToString());
                            bool[] chk = DecodeDays(curData.Data_GetField(1).ToString());
                            for (int i = 0; i < chk.Length; i++)
                            {
                                if (chk[i])
                                {
                                    switch (i)
                                    {
                                        case 0:
                                            chkMon.Checked = true;
                                            break;
                                        case 1:
                                            chkTue.Checked = true;
                                            break;
                                        case 2:
                                            chkWed.Checked = true;
                                            break;
                                        case 3:
                                            chkThu.Checked = true;
                                            break;
                                        case 4:
                                            chkFri.Checked = true;
                                            break;
                                        case 5:
                                            chkSat.Checked = true;
                                            break;
                                        case 6:
                                            chkSun.Checked = true;
                                            break;
                                    }
                                }
                            }
                        }
                        DetailControl(true);
                        break;
                }
            });
        }
        //Data Operations
        void LoadSchoolYear()
        {
            txtSchoolYear.Enabled = false;
            UnityScript u = new UnityScript("LOADSCHOOLYEAR", 5);
            u.Script_Add(Script.DBPUX_BEGIN);
            u.Script_Add(Script.DBPUX_QUERY, string.Format("SELECT fID, fData, fStamp FROM tbllookup " + 
                "WHERE (fKey='SEM_SCHOOL_YEAR' AND fData LIKE '%{0}%') ORDER BY fID DESC " +
                "LIMIT {1}, 50",
                prevSrc,
                (txtPage.Value - 1m) * 50
                ));
            u.Script_Add(Script.DBPUX_QUERY, "SELECT fID, fData ,fStamp FROM tbllookup WHERE fKey='SUBJECTS_OFFERED'");
            u.Script_Add(Script.DBPUX_QUERY, "SELECT fID, fData, fStamp FROM tbllookup WHERE fKey='ROOM_LIST'");
            u.Script_Add(Script.DBPUX_QUERY, "SELECT fID, fData, fStamp FROM tbllookup WHERE fKey='PRICE_PER_UNIT'");
            u.Script_Add(Script.DBPUX_COMMIT);
            //txtSchoolYear.Items.Add("SY 2013-2014 FIRST SEM");
            proc.Run(u);

        }
        void SaveSubjectPlanner()
        {
            txtSchoolYear.Enabled = false;
            UnityScript u = new UnityScript("SAVEPLANNER", 5);
            //u.Script_Add(Script.DBPUX_OPEN);
            string fDays = "";
            try
            {
                fDays = EncodeDays(new bool[]{
                    chkMon.Checked,
                    chkTue.Checked,
                    chkWed.Checked,
                    chkThu.Checked,
                    chkFri.Checked,
                    chkSat.Checked,
                    chkSun.Checked
                });
            }
            catch (Exception ex)
            {
                MessageBox.Show("You must select a schedule.", "Save Schedule", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            u.Script_Add(Script.DBPUX_BEGIN);
            if (AddNew)
            {
                
                u.Script_Add(Script.DBPUX_INSERT, "tblsubjectplanner(fSchoolYear, fCode, fDays, fStartTime, fEndTime, fVenue, fPrice, fUnits)",
                    new string[]{
                        txtSchoolYear.Text,
                        txtSubject.Text,
                        fDays,
                        txtStartTime.Value.ToString("HH:mm:ss"),
                        txtEndTime.Value.ToString("HH:mm:ss"),
                        txtVenue.Text,
                        txtPrice.Value.ToString(),
                        txtUnits.Value.ToString()
                    });
            }
            else
            {
                u.Script_Add(Script.DBPUX_UPDATE, string.Format("tblsubjectplanner SET " +
                    "fSchoolYear='{0}', fCode='{1}', fDays='{2}', fStartTime='{3}', fEndTime='{4}', fVenue='{5}', fPrice='{6}', fUnits='{7}'",
                    txtSchoolYear.Text,
                    txtSubject.Text,
                    fDays,
                    txtStartTime.Value.ToString("HH:mm:ss"),
                    txtEndTime.Value.ToString("HH:mm:ss"),
                    txtVenue.Text,
                    txtPrice.Value.ToString(),
                        txtUnits.Value.ToString()
                    ),
                    string.Format("(fID='{0}') AND (fStamp='{1}')", curData.Data_ID.ToString(), curData.Data_Stamp));
            }
            u.Script_Add(Script.DBPUX_QUERY, string.Format("SELECT fID, fCode AS 'Subject', fDays AS 'Days', TIME_FORMAT(fStartTime, '%r') AS 'Start', " +
                "TIME_FORMAT(fEndTime, '%r') AS 'End', fVenue AS 'Venue',fPrice AS 'Subject Price', fUnits AS 'No. of Units', fStamp FROM tblsubjectplanner " +
                "WHERE fSchoolYear='{0}'",
                txtSchoolYear.Text
                )
                );
            u.Script_Add(Script.DBPUX_COMMIT);
            proc.Run(u);
        }
        void DeleteStudentProfile()
        {
            txtSchoolYear.Enabled = false;
            UnityScript u = new UnityScript("DELETEUSER", 5);
            u.Script_Add(Script.DBPUX_BEGIN);

            u.Script_Add(Script.DBPUX_DELETE, "tblsubjectplanner",
                string.Format("(fID='{0}') AND (fStamp='{1}')", curData.Data_ID.ToString(), curData.Data_Stamp));

            u.Script_Add(Script.DBPUX_QUERY, string.Format("SELECT fID, fCode AS 'Subject', fDays AS 'Days', TIME_FORMAT(fStartTime, '%r') AS 'Start', " +
                "TIME_FORMAT(fEndTime, '%r') AS 'End', fVenue AS 'Venue',fPrice AS 'Subject Price', fUnits AS 'No. of Units', fStamp FROM tblsubjectplanner " +
                "WHERE fSchoolYear='{0}'",
                txtSchoolYear.Text
                )
                );
            u.Script_Add(Script.DBPUX_COMMIT);
            proc.Run(u);
        }
        void LoadSubjectPlanner()
        {
            UnityScript u = new UnityScript("LOADPLANNER", 2);
            u.Script_Add(Script.DBPUX_BEGIN);
            u.Script_Add(Script.DBPUX_QUERY, string.Format("SELECT fID, fCode AS 'Subject', fDays AS 'Days', TIME_FORMAT(fStartTime, '%r') AS 'Start', " + 
                "TIME_FORMAT(fEndTime, '%r') AS 'End', fVenue AS 'Venue',fPrice AS 'Subject Price', fUnits AS 'No. of Units', fStamp FROM tblsubjectplanner " +
                "WHERE fSchoolYear='{0}'",
                txtSchoolYear.Text
                )
                );
            u.Script_Add(Script.DBPUX_COMMIT);
            proc.Run(u);
        }
        string EncodeDays(bool[] day)
        {
            if (day.Length < 7 || day.Length > 7)
            {
                throw new Exception("Invalid day length.");
            }
            string res = "";
            for (int i = 0; i < 7; i++)
            {
                if (day[i])
                {
                    switch (i)
                    {
                        case 0:
                            res += "M";
                            break;
                        case 1:
                            res += "T";
                            break;
                        case 2:
                            res += "W";
                            break;
                        case 3:
                            res += "Th";
                            break;
                        case 4:
                            res += "F";
                            break;
                        case 5:
                            res += "S";
                            break;
                        case 6:
                            res += "Su";
                            break;
                    }
                    if (i < 6) res += "-";
                }
            }
            if (res.Substring(res.Length - 1, 1) == "-") res = res.Substring(0, res.Length - 1);
            return res;
        }
        bool[] DecodeDays(string day)
        {
            bool[] res = new bool[7];
            string[] tmp = day.Split('-');
            for (int i = 0; i < tmp.Length; i++)
            {
                switch (tmp[i])
                {
                    case "M":
                        res[0] = true;
                        break;
                    case "T":
                        res[1] = true;
                        break;
                    case "W":
                        res[2] = true;
                        break;
                    case "Th":
                        res[3] = true;
                        break;
                    case "F":
                        res[4] = true;
                        break;
                    case "S":
                        res[5] = true;
                        break;
                    case "Su":
                        res[6] = true;
                        break;
                }
            }
            return res;
        }

        //GUI Operations
        void DetailControl(bool s)
        {
            grdItems.Enabled = !s;
            grpDetails.Visible = s;
            grpDetails.Enabled = s;
            btnAdd.Enabled = !s;
            txtSearch.Enabled = !s;
            txtPage.Enabled = !s;
            txtSchoolYear.Enabled = !s;
        }
        void FormatGrid()
        {
            foreach (DataGridViewColumn col in grdItems.Columns)
            {
                col.Width = (grdItems.Width / grdItems.Columns.Count) - 10;
                col.SortMode = DataGridViewColumnSortMode.NotSortable;
            }
        }
        private DateTime RoundOffTime(TimeSpan curTime)
        {
            curTime = new TimeSpan(curTime.Hours, curTime.Minutes, 0);
            if (curTime.Minutes < 15)
            {
                curTime = new TimeSpan(curTime.Hours, 0, 0);
            }
            else if (curTime.Minutes > 15 && curTime.Minutes < 30)
            {
                curTime = new TimeSpan(curTime.Hours, 30, 0);
            }
            else if (curTime.Minutes > 30 && curTime.Minutes < 45)
            {
                curTime = new TimeSpan(curTime.Hours, 30, 0);
            }
            else if (curTime.Minutes > 45 && curTime.Minutes < 59)
            {
                curTime = new TimeSpan(curTime.Hours + 1, 0, 0);
            }
            DateTime res = DateTime.Parse(string.Format("{0}:{1}:{2}", curTime.Hours, curTime.Minutes, curTime.Seconds)); 
            return res;
        }
    }
}
